#pragma once

#include <string>

#include "../TermSystem.hpp"

namespace terms {
	namespace dl {
		enum class DLTermOrder {
			FIRST,
			INDIVIDUAL,
			THING,
			CLASS,
			NOTHING,
			OBJECT_INTERSECTION,
			OBJECT_UNION,
			IMPLIES,
			OBJECT_SOME_RESTRICTION,
			OBJECT_ALL_RESTRICTION,
			OBJECT_MIN_CARDINALITY,
			OBJECT_MAX_CARDINALITY,
			OBJECT_NEGATION,
			LITERAL,
			DATA_INTERSECTION,
			DATA_UNION,
			DATATYPE_EXPRESSION,
			DATA_SOME_RESTRICTION,
			DATA_ALL_RESTRICTION,
			DATA_MIN_CARDINALITY,
			DATA_MAX_CARDINALITY,
			DATA_NEGATION,
			LAST
		};

		template <typename L=std::string, typename I=std::string, typename C=std::string, typename R=std::string>
		class DLTerm
			: public terms::TermSystem<DLTerm<L, I, C, R>, DLTermOrder>
		{
		public:
			virtual void visit(TermVisitor<DLTerm> &visitor) const
			{
				visitor.visitBefore(*this);
				visitor.visit(*this);
				visitor.visitAfter(*this);
			}
		};
	}
}
